package com.qust.enDecrpytion.looPool;

import com.qust.util.NettyUtils;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import lombok.extern.log4j.Log4j2;

import java.util.HashMap;
import java.util.Map;
@Log4j2
public class ChannelLooPool extends AbstractLooPool<Map<Channel, NettyUtils.MessageHandle>>{
    public ChannelLooPool(int nOfCore, int nOfMax) {
        super(nOfCore, nOfMax);
    }


    @Override
    public synchronized Node<Map<Channel, NettyUtils.MessageHandle>> getIdleNode() {
        for (int i = 0; i < stack.size(); i++) {
            Node<Map<Channel, NettyUtils.MessageHandle>> pop = stack.pop();
            Channel next = pop.getNode().keySet().iterator().next();
            if (!next.isActive()) {
                log.warn("远程主机掉线,地址:{}",next.remoteAddress());
                this.remove(pop);
            }else {
                pop.setStatus(Status.busy);
                return pop;
            }
        }
        return null;
    }

    public synchronized Node<Map<Channel, NettyUtils.MessageHandle>> getIdleNode(EventLoopGroup eventLoopGroup){
        if (this.stack.isEmpty()) {
            log.warn("没有空闲连接");
            if (this.nOfOther + this.nOfCore < this.nOfMax) {
                log.debug("允许创建暂时连接,创建中...");
                return createChannel(eventLoopGroup);
            }else {
                log.error("以达到最大连接数,无法创建连接,请及时处理");
                return createChannel(eventLoopGroup);
            }
        }else {
            return getIdleNode();
        }
    }

    private Node<Map<Channel, NettyUtils.MessageHandle>> createChannel(EventLoopGroup eventLoopGroup) {
        for (Node<Map<Channel, NettyUtils.MessageHandle>> node : this.nodes) {
            Map<Channel, NettyUtils.MessageHandle> data = node.getNode();
            Channel next1 = data.keySet().iterator().next();
            String address = next1.remoteAddress().toString(); // /127.0.0.1:8132
            String[] ipPort = address.substring(address.indexOf("/")).split(":");
            NettyUtils.MessageHandle messageHandle = new NettyUtils.MessageHandle();
            Channel channel = NettyUtils.generateChannel(ipPort[0], Integer.parseInt(ipPort[1]), eventLoopGroup, messageHandle);
            Map<Channel, NettyUtils.MessageHandle> map = new HashMap<>();
            map.put(channel,messageHandle);
            return new Node<>(map);
        }
        return null;
    }
}
